#ifndef TCPU_H
#define TCPU_H

#include <map>
#include <functional>
#include <QObject>
#include <QString>
#include <unordered_map>

class QString;
class Session;
class Task;
class TCpu : public QObject
{
    Q_OBJECT
public:
    // Typedefs
    using TaskProcessFunctionType = std::function<void(QVariantMap)>;
private:
    TCpu(QObject *parent = nullptr);
public:
    ~TCpu();
public:
    void pause();
    void resume();
    bool isPaused() { return _paused; }
    void togglePause() { return isPaused() ? resume() : pause(); }
    // methods :
    void on(int channel, const QString &type, QVariantMap obj);

    template <class T>
    void setOn(int channel, const QString &type, T *thisptr, void (T::* func)(QVariantMap));
    void setOn(int channel, const QString &type, TaskProcessFunctionType func);
//private:
public:
    // internal variables
    std::unordered_map<int, std::unordered_map<std::string, TaskProcessFunctionType>> tasks;
private:
    volatile bool _paused = false;
public:
    // public static functions
    static TCpu *instance();
private:
    static TCpu *_instance;
};

template <class T>
inline void TCpu::setOn(int channel, const QString &type, T *thisptr, void (T::* func)(QVariantMap))
{
    return setOn(channel, type, std::bind(func, thisptr, std::placeholders::_1));
}

#endif // TCPU_H
